react hooks 使用实例


react hooks 使用实例

通过reducer来处理dispatch出来的各种action

reducer.ts

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
export const dataFetchReducer = (state: any, action: {[type: string]: any}) => {
switch(action.type) {
case 'FETCH_INIT':
return {
...state,
isLoading: true,
isError: false
}
case 'FETCH_SUCCESS':
return {
...state,
isLoading: false,
isError: false
data: action.payload
}
case 'FETCH_ERROR':
return {
...state,
isLoading: false,
isError: true,
msg: action.payload
}
default:
throw new Error(`Unsupport action type:${action.type}`);
}
}

自定义一个获取数据的React Hooks

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
interface RequestConfig extends AxiosRequestConfig{
url: string
}

exports const useDataApi = (initData: Array<any> | any, initRequestConfig: RequestConfig) {
if (!initRequstConfog.method) {
initRequstConfog.method = "get";
}
const [requestConfig, setRequestConfig] = useState(initRequestConfig);
const [state, dispatch] = useReducer(dataFetchReducer, {
data: initData,
isLoading: false,
isError: false
});

useEffect(() => {
const fetchData = async () => {
try {
dispatch({
type: 'FETCH_INIT'
});
if (!requestConfig.url) {
dispatch({
type: 'FETCH_SUCCESS',
payload: []
});
} else {
const response = await axios(requestConfig).catch(e => return e.response);
if (response.data) {
const data = response.data;
const { success, result, message } = data;
if (!success) {
dispatch({
type: 'FETCH_ERROR',
payload: message
});
} else {
dispatch({
type: 'FETCH_SUCCESS',
payload: result
});
}
} else {
dispatch({
type: 'FETCH_ERROR',
payload: '加载数据失败'
});
}
}
} catch(error) {
dispatch({
type: 'FETCH_ERROR'
msg: '加载数据失败'
});
}
}
}, [requestConfig]);
return [state, setRequestConfig]
}

使用自定义的Hooks来加载数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
const [{isLoading, isError, msg, data}, setRequestConfig] = useDataApi([], {url: apiPath});
if (isError) {
message.error(msg);
return (
<div>
<div className="toolbar">
<Link to={window.location.pathname+ '/detail'} >
<Button type="primary" icon="plus" >
添加
</Button>
</Link>
</div>
<CustomModal />
<Table columns={columns}
dataSource={data}
loading={isLoading}
rowKey={'id'} />
</div>
)
}